﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DotRas;
using Microsoft.VisualBasic;

namespace VPNLaunch
{
  /// <summary>
  /// Testing commit emails
  /// </summary>
  public partial class frmConnectionManager : Form
  {
    /// <summary>
    /// User Settings 
    /// </summary>
    private UserSettings userSettings;

    /// <summary>
    /// Phone book entries for current user.
    /// </summary>
    private RasPhoneBook pb = new RasPhoneBook();

    /// <summary>
    /// Delegate that allows notification of Active connection
    /// </summary>
    public delegate void ActiveConnectionChangedHandler(object sender, VpnLaunchEventArgs e);
    public event ActiveConnectionChangedHandler ActiveConnectionChanged;
    public virtual void OnActiveConnectionChanged(VpnLaunchEventArgs e)
    {
      if (ActiveConnectionChanged != null)
        ActiveConnectionChanged(this, e);
    }

    /// <summary>
    /// Form Constructor
    /// </summary>
    public frmConnectionManager()
    {
      InitializeComponent();
    }

    /// <summary>
    /// Private event that fires when form loads.
    /// 
    /// Opening Phonebook for current user and getting their settings.
    /// 
    /// Connections will equal null for the first time they run this program
    /// because no user settings connections will have been defined.
    /// 
    /// Connection will equal zero if all connections have been erased
    /// or no connections exist on the current machine.
    /// 
    /// </summary>
    private void frmConnectionManager_Load(object sender, EventArgs e)
    {
      pb.Open(true);
      this.userSettings = new UserSettings();

      if (this.userSettings.Connections == null || this.userSettings.Connections.Count == 0)
      {
        this.userSettings.Connections = PopulateEntries();
        this.userSettings.Save();
        this.userSettings.Reload();
      }
      //ShowActiveConnection();
      this.ddlConnections.Items.AddRange(this.userSettings.Connections.ToArray());
      if (ddlConnections.Items.Count == 1)
        ddlConnections.SelectedIndex = 0;

    }

    /// <summary>
    /// Save all the user settings.  
    /// 
    /// If a user changes the active connections settings I need to change the 
    /// activeconnection property on the main form.  Currently I'm just using 
    /// this event.  Suggestions?
    /// </summary>
    private void btnSave_Click(object sender, EventArgs e)
    {
      this.userSettings.Save();
      var entry = this.userSettings.Connections.SingleOrDefault(c => c.DefaultConnection == true);
      if (entry != null)
        ActiveConnectionChanged(this, new VpnLaunchEventArgs() { ActiveConnection = entry });
      this.Close();
    }
    private void ShowActiveConnection()
    {
      ConnectionInfo connection = this.userSettings.Connections.SingleOrDefault(c => c.DefaultConnection == true);
    }

    //private void btnActivate_Click(object sender, EventArgs e)
    //{
    //  if (this.ddlConnections.SelectedItem != null)
    //  {
    //    foreach (ConnectionInfo entry in this.userSettings.Connections)
    //      entry.DefaultConnection = false;
    //    ((ConnectionInfo)this.ddlConnections.SelectedItem).DefaultConnection = true;
    //    ShowActiveConnection();
    //    this.userSettings.Save();
    //    ActiveConnectionChanged(this, new VpnLaunchEventArgs() { ActiveConnection = (ConnectionInfo)this.lbConnections.SelectedItem });
    //  }
    //}

    private void btnDelete_Click(object sender, EventArgs e)
    {
      if (ddlConnections.SelectedIndex > -1)
      {
        DialogResult msgResult = MessageBox.Show(this, string.Format("Are you sure you want to delete [{0}]?", ddlConnections.SelectedItem.ToString()), "Confirm", MessageBoxButtons.YesNo);
        if (msgResult == DialogResult.Yes)
        {
          ConnectionInfo entry = (ConnectionInfo)this.ddlConnections.SelectedItem;
          ddlConnections.Items.Remove(this.ddlConnections.SelectedItem);
          this.pb.Entries.Remove(entry.ConnectionName);
          this.userSettings.Connections.Remove(entry);
          this.userSettings.Save();
          this.btnDelete.Enabled = this.ddlConnections.Items.Count != 0;
          propertyGrid1.SelectedObject = null;
        }
      }
    }

    private List<ConnectionInfo> PopulateEntries()
    {
      return pb.Entries.Select(entry => new ConnectionInfo()
      {
        ConnectionName = entry.Name,
        Id = entry.Id
      }).ToList();
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
      this.Close();
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
      try
      {
        string NewConnName = Interaction.InputBox("Enter Connection Name", "New Connection", "", MousePosition.X - 200, MousePosition.Y);
        if (NewConnName.Length > 0)
        {
          if (pb.Entries.FirstOrDefault(a => a.Name.ToLower() == NewConnName.ToLower()) == null)
          {
            RasEntry entry = RasEntry.CreateVpnEntry(NewConnName, "john.doe.com",
                RasVpnStrategy.Default, RasDevice.GetDeviceByName("(PPTP)", RasDeviceType.Vpn, false));
            entry.Options = RasEntryOptions.SpecificNameServers | RasEntryOptions.ModemLights | RasEntryOptions.RequireEncryptedPassword |
            RasEntryOptions.RequireDataEncryption | RasEntryOptions.PreviewUserPassword | RasEntryOptions.PreviewDomain | RasEntryOptions.ShowDialingProgress |
            RasEntryOptions.RequireChap | RasEntryOptions.RequireMSChap2;
            this.pb.Entries.Add(entry);
            this.userSettings.Connections.Add(new ConnectionInfo()
            {
              Id = entry.Id,
              ConnectionName = entry.Name,
              Routes = new List<Route>(),
              DefaultConnection = false
            });
            this.userSettings.Save();
            this.ddlConnections.Items.Clear();
            this.ddlConnections.Items.AddRange(this.userSettings.Connections.ToArray());
            ddlConnections.SelectedIndex = ddlConnections.FindStringExact(NewConnName);
          }
          else
          {
            MessageBox.Show(this, "There is already an entry with that name", "Duplicate Entry", MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
        }
      }
      catch (ArgumentException ex)
      {
        MessageBox.Show(ex.Message);
      }

      //try
      //{
      //  RasEntry entry = RasEntry.CreateVpnEntry(String.Format("Harris-{0}",DateTime.Now.ToString("hh-mm-ss")), "vpn.multimax.com",
      //      RasVpnStrategy.Default, RasDevice.GetDeviceByName("(PPTP)", RasDeviceType.Vpn, false));
      //  entry.Options = RasEntryOptions.SpecificNameServers | RasEntryOptions.ModemLights | RasEntryOptions.RequireEncryptedPassword |
      //    RasEntryOptions.RequireDataEncryption | RasEntryOptions.PreviewUserPassword | RasEntryOptions.PreviewDomain | RasEntryOptions.ShowDialingProgress |
      //    RasEntryOptions.RequireChap | RasEntryOptions.RequireMSChap2;
      //  this.pb.Entries.Add(entry);
      //  this.userSettings.Connections.Add(new ConnectionInfo()
      //  {
      //    Id = entry.Id,
      //    ConnectionName = entry.Name,
      //    Routes = new List<Route>(),
      //    DefaultConnection = false
      //  });
      //  this.userSettings.Save();
      //  //this.lbConnections.Items.Clear();
      //  //this.lbConnections.Items.AddRange(this.userSettings.Connections.ToArray());
      //}
      //catch(ArgumentException ex)
      //{
      //  MessageBox.Show(ex.Message);
      //}
    }

    private void ddlConnections_SelectedIndexChanged(object sender, EventArgs e)
    {
      this.btnDelete.Enabled = true;
      this.propertyGrid1.SelectedObject = (ConnectionInfo)this.ddlConnections.SelectedItem;
    }
  }
}
